<template>
  <div class="box">
    <div>
      <a-button style="color: white;margin-left: 5px" v-action="'form'" type="link">权限 表单</a-button>
      <a-button style="color: white;margin-left: 5px" v-action="'aaaaaaaa'" type="link">权限 添加1</a-button>
    </div>
    <div style="margin-top: 20px;">
      <a-upload drag multiple :auto-upload="true" :limit="10" :customRequest="uploadFile">
        <i class="el-icon-upload"></i>
        <div class="el-upload__text">
          将文件拖到此处，或
          <em>点击上传</em>
        </div>
      </a-upload>
      <a-progress
        type="circle"
        :percent="progress"
        class="progress"
        v-if="showProgress"
      />
    </div>
    
  </div>
</template>
  <script>
import SparkMD5 from 'spark-md5'
export default {
  data() {
    return {
      // 进度
      showProgress: false,
      progress: 0,
      // 定义切片的数据配型
      FileData: {
        file: 'any',
        uploaded: 'boolean',
        hash: 'string',
        chunkIndex: 'number',
        chunkCount: 'string',
        fileName: 'string',
      },
      HashData: {
        hash: 'string',
        fileName: 'string',
        prss: 'number',
        speep: 'number',
      },
      // 选择的文件的 File 数组（可能选择了多个文件）
      filesArr: [],
      // 切片后的文件集合（不论是一个 还是多个文件，切片后都会在这个数组里）
      fileDataArr: [],
      hashDataArr: [],
      chunkSize: 1024 * 1024 * 2, // 切片的大小 2Mb
    }
  },
  mounted() {},
  methods: {
    // 计算出文件的MD5值的公共方法
    // 配合js的 FileReader 函数来使用 SparkMD5
    getFileMD5(file) {
      return new Promise((resolve, reject) => {
        const spark = new SparkMD5.ArrayBuffer()
        const fileReader = new FileReader()
        fileReader.onload = e => {
          spark.append(e.target.result)
          resolve(spark.end())
        }
        fileReader.onerror = () => {
          reject('')
        }
        fileReader.readAsArrayBuffer(file)
      })
    },
    // 选择文件事件方法
    uploadFile(info) {
      const fileEle = info
      this.filesArr = [fileEle.file]
      this.hashDataArr = []
      console.log(this.filesArr, '--')

      this.showProgress = true
      // 循环选中的每一个文件
      this.filesArr.forEach(async file => {
        // 当前文件大小
        const fileSize = file.size
        // 当前文件 分割 多少份 （chunkSize 多少大小分割）
        let chunkCount = Math.ceil(fileSize / this.chunkSize)
        if (fileSize > this.chunkSize * 100) {
          this.chunkSize = this.chunkSize * 20
          chunkCount = Math.ceil(fileSize / this.chunkSize)
        }
        console.log(this.chunkSize, chunkCount, '====')
        // 给每个文件 生成 唯一的md5 值 （md值的变化和文件名称无关，和文件里的内容改动有关）
        const hash = await this.getFileMD5(file)
        console.log(hash, 'hash')

        this.hashDataArr.push({
          hash: hash,
          fileName: file.name,
          prss: 0,
          speep: 0,
        })

        for (let i = 0; i < chunkCount; i++) {
          // 当前 分割 开始点
          const startPoint = i * this.chunkSize
          // 当前分割 结束点
          const endPoint = Math.min(startPoint + this.chunkSize, fileSize)
          const chunk = file.slice(startPoint, endPoint)
          // 如你门需要 FormData 方式 那就打开 下面的注释
          // const fd = new FormData()
          // fd.append('file', chunk)
          // fd.append('chunkIndex', i.toString())
          // fd.append('chunkCount', chunkCount.toString())
          // fd.append('fileName', file.name)
          // fd.append('hash', hash)
          // 往数组里 塞切片（如果你门时 FormData 那么就把 下面file： chunk 改为 file：fd 类型改 FormData 类型）
          this.fileDataArr.push({
            file: chunk,
            chunkCount: chunkCount.toString(),
            fileName: file.name,
            uploaded: false,
            hash,
            chunkIndex: i,
          })

          // 循环 所有切片， 循环发送服务器 并上传
          this.uploadDigFlieFun(this.fileDataArr[i])
          
          // // 更新开始 点
          // startPoint = endPoint
          // // 更新结束点
          // endPoint = startPoint + this.chunkSize
        }
      })
    },
    // 上传
    upload() {
      if (this.hashDataArr.length < this.filesArr.length) {
        alert('等待')
        return
      }
      // 循环 所有切片， 循环发送服务器
      this.fileDataArr.forEach(fileData => {
        if (!fileData.uploaded) {
          // this.uploadDigFlieFun(fileData.fd)
          this.uploadDigFlieFun(fileData)
        }
      })
    },
    // Api 大文件上传
    uploadDigFlieFun(_fileData) {
      console.log(_fileData, this.fileDataArr.length, '==================')

      // uploadDigFlie({
      //   fileName: _fileData.fileName,
      //   file: _fileData.file,
      //   chunkIndex: _fileData.chunkIndex,
      //   hash: _fileData.hash,
      //   chunkCount: _fileData.chunkCount

      // }).then(res => {
      _fileData.uploaded = true

      const index = this.hashDataArr.findIndex(item => item.hash === _fileData.hash)
      this.hashDataArr[index].speep = 100 / Number(_fileData.chunkCount)
      this.hashDataArr[index].prss += this.hashDataArr[index].speep

      this.progress = Number(parseFloat(this.hashDataArr[index].prss).toFixed(2))

      if (this.progress === 100) {
        this.progress = 0
        this.showProgress = false
      }

      console.log(_fileData.chunkIndex)
      console.log(_fileData.fileName + _fileData.chunkIndex + '--' + _fileData.chunkCount, _fileData.uploaded)
      console.log('-----------------------------------')
      // })
    },
  },
}
</script>
<style scoped lang="less">
/deep/.progress {
  /* 在当前页面居中 */
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  /* 宽度 */
}
</style>